package com.mijie.homi.service.notify;

import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.annotation.PostConstruct;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mijie.core.ApplicationProperties;
import com.mijie.homi.common.constant.CategoryCode;
import com.mijie.homi.common.constant.TypeCode;
import com.mijie.homi.common.domain.PushMessage;
import com.mijie.homi.common.domain.user.DeviceInfo;
import com.mijie.homi.common.domain.user.Setting;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.common.domain.user.UserExtInfo;
import com.mijie.homi.dao.notify.PushDao;
import com.mijie.homi.service.user.DeviceInfoService;
import com.mijie.homi.service.user.SettingService;
import com.mijie.homi.service.user.UserExtInfoService;
import com.mijie.homi.service.user.UserService;
import com.mijie.util.IPhonePushUtil;

@Service
public class PushService {

	@Autowired
	private PushDao dao;
	@Autowired
	private DeviceInfoService deviceInfoService;
	@Autowired
	private UserExtInfoService userExtInfoService;
	@Autowired
	private UserService userService;
	@Autowired
	private SettingService settingService;
	
	private static String certificatePath  = ApplicationProperties.get("iPhoneNotifyCertificatePath");
	private static String certificatePassword = "mijie";//此处注意导出的证书密码不能为空因为空密码会报错
	private static int IOS_DEVICE_TOKEN_LEN = 71;
	private static boolean test = false;
	private Logger logger = Logger.getLogger(PushService.class);
	
	private boolean pollingPushQueueWorkerIdle = true;
	private Timer timer = new Timer();
	
	
	@PostConstruct
	public void pollingPushQueue(){
		int thirtySecond = 1000 * 30;
		String testPush = ApplicationProperties.get("testPush");
		if(testPush!=null){
			test = Boolean.valueOf(testPush.trim());
		}
		
		TimerTask monitorPollingPushQueueTask = new TimerTask(){
			@Override
			public void run() {
				if(pollingPushQueueWorkerIdle){
					doPollingPushQueue();
				}
			}
		};
		timer.schedule(monitorPollingPushQueueTask, thirtySecond, thirtySecond);
	}
	
	private void doPollingPushQueue(){
		pollingPushQueueWorkerIdle = false;
		List<PushMessage> list = null;
		Iterator<PushMessage> iter = null;
		PushMessage msg = null;
		DeviceInfo deviceInfo = null;
		UserExtInfo userExt = null;
		Setting setting = null;
		User sender = null;
		boolean pushSucc = false;
		Boolean doPush = null;
		try{
			while(true){
				list = dao.listPushMessage(100);
				if(list.isEmpty()) break;
				
				logger.info("list.size:" + list.size());
				
				iter = list.iterator();
				while(iter.hasNext()){
					
					logger.info("inner while list.size:" + list.size());
					
					msg = iter.next();
					iter.remove();
					if(msg.getReceiver()==0){
						deviceInfo = deviceInfoService.getDeviceInfo(msg.getDestinationDeviceId());
					}else{
						userExt = userExtInfoService.getUserExtInfoByUserId(msg.getReceiver());
						if(userExt!=null)
							deviceInfo = deviceInfoService.getDeviceInfo(userExt.getDeviceId());
					}
					if(deviceInfo==null || certificatePath==null || certificatePassword==null){
						dao.deletePushMessages(msg.getId());
						logger.info("@@push notify ignore message because device not found,receiver:"+msg.getReceiver()+",destinationDeviceId:"+msg.getDestinationDeviceId());
						continue;
					}
					if(msg.getReceiver()!=0 && deviceInfo.getRecentUser()!=msg.getReceiver()){
						dao.deletePushMessages(msg.getId());
						logger.info("@@push notify ignore message device recent user:"+deviceInfo.getRecentUser()+",notify receiver:"+msg.getReceiver());
					}else{
						if(deviceInfo.getDeviceId().equals("deviceTokenError")){
							dao.deletePushMessages(msg.getId());
							logger.info("@@push notify ignore message because device token error.");
						}else{
							if(msg.getReceiver()!=0)
								setting = settingService.getSettingByUserId(msg.getReceiver());
							else 
								setting = settingService.getSettingByUserId(deviceInfo.getRecentUser());
							if(setting == null){
								dao.deletePushMessages(msg.getId());
								logger.info("@@push notify ignore message because user setting is null.msg.receiver:"+msg.getReceiver()+",device recent user:"+deviceInfo.getRecentUser());
								continue;
							}
							
							JSONObject json = null;
							int category = 0;
							switch (msg.getContentType()){
							case TypeCode.FRIEND_REQUEST:
//								doPush = setting.getReceiveFriendRequestMsg()==1;
								json = JSONObject.fromObject(msg.getContent());
								category = json.getInt("category");
								if(category==CategoryCode.FRIEND_REQUEST_INFO){
									msg.setContent(json.getString("nickName")+" 请求加您为好友");
								}else if(category==CategoryCode.FRIEND_REQUEST_ACCEPT){
									msg.setContent(json.getString("nickName")+" 同意加您为好友");
								}else if(category==CategoryCode.FRIEND_REQUEST_REJECT){
									msg.setContent(json.getString("nickName")+" 拒绝加您为好友");
								}else{
									dao.deletePushMessages(msg.getId());
									continue;
								}
								break;
							case TypeCode.MOOD_VIEWAPPLY:
//								doPush = setting.getReceivePrivacyApplyMsg()==1;
								json = JSONObject.fromObject(msg.getContent());
								category = json.getInt("category");
								if(category==CategoryCode.MOOD_VIEWAPPLY_INFO){
									msg.setContent(json.getString("applicantNickName")+" 申请查看您的心情");
								}else if(category==CategoryCode.MOOD_VIEWAPPLY_ACCEPT){
									msg.setContent(json.getString("masterNickName")+" 同意您查看"+(json.getInt("masterGender")==1?"他":"她")+"的心情");
								}else if(category==CategoryCode.MOOD_VIEWAPPLY_REJECT){
									msg.setContent(json.getString("masterNickName")+" 拒绝您查看"+(json.getInt("masterGender")==1?"他":"她")+"心情");
								}else{
									dao.deletePushMessages(msg.getId());
									continue;
								}
								break;
							case TypeCode.PRIVACY_APPLY:
//								doPush = setting.getReceivePrivacyApplyMsg()==1;
								json = JSONObject.fromObject(msg.getContent());
								msg.setContent(json.getString("content"));
								break;
							case TypeCode.NEW_TOPIC:
//								doPush = setting.getReceiveFriendNewTopic()==1;
								msg.setContent("您有好友发布了新的问题，进去帮忙回答吧");
								break;
							case TypeCode.AUDIT:
//								doPush = setting.getReceiveTopicVerifyResult()==1;
								json = JSONObject.fromObject(msg.getContent());
								category = json.getInt("category");
								if(category==CategoryCode.AUDIT_PASS){
									msg.setContent("您所发布的问题已被管理员审核通过啦");
								}else if(category==CategoryCode.AUDIT_REJECT){
									msg.setContent("您所发布的问题未被管理员审核通过");
								}else{
									dao.deletePushMessages(msg.getId());
									continue;
								}
								break;
							case TypeCode.TOPIC_OPINION:
//								doPush = setting.getReceiveTopicOpinion()==1;
								msg.setContent("您所发布的问题有了新的看法");
								break;
							case TypeCode.PROSECUTE:
//								doPush = setting.getReceiveProsecuteResult()==1;
								msg.setContent("您的举报内容已经有处理结果了，快去查看吧");
								break;
							case TypeCode.REPLY:
//								doPush = setting.getReceiveNewReview()==1;
								json = JSONObject.fromObject(msg.getContent());
								category = json.getInt("category");
								if(category==CategoryCode.REPLY_MOOD){
									msg.setContent("您的心情评论里有新的回复消息");
								}else if(category==CategoryCode.REPLY_PHOTO){
									msg.setContent("您的照片评论里有新的回复消息");
								}else if(category==CategoryCode.REPLY_TOPIC){
									sender = userService.getUserById(json.getInt("reviewer"));
									msg.setContent(sender.getNickName()+" 在现实映射里@了您");
								}else{
									dao.deletePushMessages(msg.getId());
									continue;
								}
								break;
							case TypeCode.COMMENT:
//								doPush = setting.getReceiveNewReview()==1;
								json = JSONObject.fromObject(msg.getContent());
								category = json.getInt("category");
								if(category==CategoryCode.COMMENT_MOOD){
									msg.setContent("您的心情有新的评论");
								}else if(category==CategoryCode.COMMENT_PHOTO){
									msg.setContent("您的照片有新的评论");
								}else if(category==CategoryCode.COMMENT_TOPIC){
									msg.setContent("您的话题看法有新的评论");
								}else{
									dao.deletePushMessages(msg.getId());
									continue;
								}
								break;
							default : doPush = true;
							}

							if(doPush==null)
								doPush = setting.getNotifyPushable().equals(1);
							
							if(doPush){
								if(deviceInfo.getDeviceId().length()>=IOS_DEVICE_TOKEN_LEN){
									dao.deletePushMessages(msg.getId());
									continue;
								}
								pushSucc = IPhonePushUtil.pushNotify(deviceInfo.getDeviceId(), certificatePath, certificatePassword, msg.getContent(), deviceInfo.getUnreadNotifyCount()+1, test);
								if(pushSucc){
									deviceInfoService.incrDeviceUnreadNotifyCount(deviceInfo.getDeviceId(), 1);
									dao.deletePushMessages(msg.getId());
									logger.info("@@push notify["+msg.getId()+"]:"+msg.getContent());
								}
							}else{
								dao.deletePushMessages(msg.getId());
							}
						}
					}
				}
			}
		}catch (NumberFormatException numEx) {
			dao.deletePushMessages(msg.getId()); 
			logger.error(numEx.getMessage(), numEx);
		}catch(Exception e){
			logger.error(e.getMessage(), e);
		}finally{
			pollingPushQueueWorkerIdle = true;
		}
	}
	
	
	public int addToPushQueue(PushMessage message){
		if(message.getIdx()==0) message.setIdx(System.currentTimeMillis());
		if(message.getDestinationDeviceId()==null) message.setDestinationDeviceId("");
		return dao.addToPushQueue(message);
	}
	
	public int batchAddToPushQueue(List<PushMessage> list){
		return dao.batchAddToPushQueue(list);
	}
	
	
}
